<template>
  <div id="canvas"></div>
  <button type="button" @click="exportDiagram">导出</button>
</template>

<script setup>
import BpmnModeler from "bpmn-js/lib/Modeler"
import 'bpmn-js/dist/assets/diagram-js.css' // 左边工具栏以及编辑节点的样式
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
import xmlStr from '../xmlStr';
import customModule from './custom'
import activitiModdel from '../resources/activiti-moddel.json'
import { nextTick, onMounted, ref } from "vue";
import {
    append as svgAppend,
    attr as svgAttr,
    create as svgCreate,
    innerSVG
} from 'tiny-svg';
import { query as domQuery } from 'min-dom';

const viewer = ref()

onMounted(() => {
  viewer.value = new BpmnModeler({
    container: document.querySelector('#canvas'),
    additionalModules: [customModule],
    moddleExtensions: {
      activiti: activitiModdel,
    }
  });

  viewer.value.importXML(xmlStr, function(err) {
    if (!err) {
      console.log('success!');
      const canvas = viewer.value.get('canvas');
      canvas.zoom('fit-viewport');
      canvas.addMarker('Flow_19u6io8', 'highlight-line');
      setMarkerEndStyle()
    } else {
      console.log('something went wrong:', err);
    }
  })

  nextTick(() => {
    const list = [
      { name: 'a', value: '1' },
      { name: 'b', value: '2' },
      { name: 'c', value: '3' },
    ]
    const elementRegistry = viewer.value.get('elementRegistry');
    const modeling = viewer.value.get('modeling');
    const moddle = viewer.value.get('moddle');
    const element = elementRegistry.get('Activity_19xf9f7');
    const properties = moddle.create(`activiti:Properties`, {
      values: list.map(item => {
        return moddle.create(`activiti:Property`, { name: item.name, value: item.value });
      }),
    });
    const extensionElements = element.businessObject?.extensionElements;
    const otherExtensions = extensionElements?.values?.filter((ex) => ex.$type !== elementName) || [];
    const extensions = moddle.create('bpmn:ExtensionElements', {
      values: otherExtensions.concat(properties),
    });
    modeling.updateProperties(element, {
      extensionElements: extensions,
    })
  })
})

const exportDiagram = () => {
  viewer.value.saveXML({ format: true }, function(err, xml) {
    if (!err) {
      console.log(xml);
    } else {
      console.log('something went wrong:', err);
    }
  });
}

const setMarkerEndStyle = () => {
  const normalMarker = svgCreate('marker')
  const excutedMarker = svgCreate('marker')
  svgAttr(normalMarker, {
    id: 'sequenceflow-arrow-normal',
    viewBox: '0 0 20 20',
    refX: '11',
    refY: '10',
    markerWidth: '50',
    markerHeight: '50',
    orient: 'auto',
  })
  svgAttr(excutedMarker, {
    id: 'sequenceflow-arrow-excuted',
    viewBox: '0 0 20 20',
    refX: '11',
    refY: '10',
    markerWidth: '50',
    markerHeight: '50',
    orient: 'auto',
  })
  const path = svgCreate('path')
  svgAttr(path, {
    d: 'M 1 5 L 11 10 L 1 15 Z',
    style: ' stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: rgb(214, 214, 214) !important; fill: rgb(214, 214, 214) !important;',
  })
  const excutedPath = svgCreate('path')
  svgAttr(excutedPath, {
    d: 'M 1 5 L 11 10 L 1 15 Z',
    style: ' stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; stroke: rgb(0, 0, 0) !important; fill: rgb(27, 143, 255) !important;',
  })
  const defs = domQuery('defs')
  svgAppend(normalMarker, path)
  svgAppend(defs, normalMarker)
  svgAppend(excutedMarker, excutedPath)
  svgAppend(defs, excutedMarker)
}
</script>

<style>
.node-wrapper {
  border: 1px solid green
}
.highlight-line g.djs-visual >:nth-child(1) {
  stroke: blue !important;
}
.highlight-line {
  .djs-visual {
    path {
      marker-end: url('#sequenceflow-arrow-excuted') !important;
    }
  }
}
</style>
<style scoped>
#canvas {
  width: 500px;
  height: 800px;
}
</style>
